package com.m3958.encode.detector;

import java.nio.file.Path;
import java.util.Iterator;

import com.m3958.encode.detector.exception.FileOpenException;
import com.m3958.encode.detector.exception.UndetectableException;

public class Detectors {
    
    
    private LanguageName ln;
    
    private byte[] bytes;
    
    private Path path;
    
    private Detector mostPossibility;
    
    private boolean entireFile;
    
    public Detectors prefer(LanguageName ln) {
        this.ln = ln;
        return this;
    }
    
    public Detectors scanWholeFile() {
        this.entireFile = true;
        return this;
    }


    public Detector detect(byte[] bytes) throws UndetectableException {
        this.bytes = bytes;
        try {
            return dt();
        } catch (FileOpenException e) {
            e.printStackTrace();
        }
        throw new UndetectableException(mostPossibility);
    }
    
    private Detector dt() throws FileOpenException {
        AbstractDetector dc = null;
        Iterator<Class<? extends AbstractDetector>> it = DetactorClazz.detectorIterator(ln);
        while(it.hasNext()) {
            try {
                dc = it.next().newInstance();
                if (bytes == null) {
                    dc.setPath(path);
                } else {
                    dc.setBytes(bytes);
                }
                
                if (entireFile) {
                    dc.scanWholeFile();
                }
                
                if (dc.detect().result().successPercent() == 100) {
                    return dc;
                } else {
                    assignMostPossibility(dc);
                }
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } 
        }
        return dc;
    }
    
    private void assignMostPossibility(AbstractDetector dc) {
        if (mostPossibility == null) {
            mostPossibility = dc;
        } else {
            if (dc.result().successPercent() > mostPossibility.result().successPercent()) {
                mostPossibility = dc;
            }
        }
    }
}
